﻿using System;
using System.Globalization;
using System.Reflection;
using System.Security;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace OpenWaves.ActivityFeed.Sharepoint
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    //[Guid("7579d542-bd7d-4f2f-9cd2-9721f1d9099b")]
    public abstract class ActivityFeedFeatureReceiverBase : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            try
            {
                var web = properties.Feature.Parent as SPWeb;
                if (web == null)
                {
                    var site = properties.Feature.Parent as SPSite;
                    
                    if (site == null)
                    {
                        throw new SPException("Cannot activate feature");
                    }
                    foreach (SPWeb siteWeb in site.AllWebs)
                    {
                        SPListCollection lstCollection = siteWeb.Lists;
                        this.AddEventReciversToLists(lstCollection);
                    }
                }
                else
                {
                    SPListCollection lstCollection = web.Lists;
                    this.AddEventReciversToLists(lstCollection);
                }
            }
            catch (Exception eEX)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("ActivityFeed", TraceSeverity.Unexpected, EventSeverity.Error),
                                TraceSeverity.Unexpected, eEX.Message, eEX.StackTrace);
            }

            try
            {
                /*
                    <connectionStrings>
                        <add name="ActivityFeed" connectionString="Url=http://localhost:8080" />
                    </connectionStrings>
                 
                    Problem: http://learningmoss.blogspot.com/2009/11/resolve-webconfigmodifications-in.html
                */

                // this.SetConnectionStirng(properties);
            }
            catch (SecurityException)
            {
            }
        }

        private void AddEventReciversToLists(SPListCollection lstCollection)
        {
            for (var i = 0; i < lstCollection.Count; i++)
            {
                var list = lstCollection[i];
                if (!this.CanAddList(list))
                {
                    continue;
                }
                //if (list.ContentTypes["MyCustomCalendarContentType"] != null)
                {
                    foreach (var eventType in new SPEventReceiverType[] { SPEventReceiverType.ItemAdded, SPEventReceiverType.ItemUpdated })
                    {
                        var eventReceiverClass = this.GetEventReceiverClassName();
                        ListEventRegistration.RegisterEventReceiver(list, eventReceiverClass, eventType);
                    }
                }
            }
        }

        protected  virtual Type GetEventReceiverClassName()
        {
            return typeof (ActivityFeedEventReceiverBase);
        }
        
        protected virtual bool CanAddList(SPList list)
        {
            return list.BaseTemplate == SPListTemplateType.DocumentLibrary ||
                   list.BaseTemplate == SPListTemplateType.WebPageLibrary;
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            try
            {
                var web = properties.Feature.Parent as SPWeb;
                if (web == null)
                {
                    var site = properties.Feature.Parent as SPSite;
                    if (site == null)
                    {
                        throw new SPException("Cannot uninstall feature");
                    }

                    for (var i = 0; i < site.AllWebs.Count; i++)
                    {
                        web = site.AllWebs[i];
                        RemoveEvents(web);
                    }
                }
                else
                {
                    RemoveEvents(web);
                }
            }
            catch (Exception eEX)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("ActivityFeedFeatureReceiverBase",
                                TraceSeverity.Unexpected, EventSeverity.Error),
                                TraceSeverity.Unexpected,
                                eEX.Message,
                                eEX.StackTrace);
            }
        }

        private static void RemoveEvents(SPWeb web)
        {
            for (var j = 0; j < web.Lists.Count; j++)
            {
                var list = web.Lists[j];
                ListEventRegistration.UnregisterAllActivityFeedEvents(list);
            }
        }


        // Uncomment the method below to handle the event raised after a feature has been installed.

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
        }

        private void SetConnectionStirng(SPFeatureReceiverProperties properties)
        {
            SPWebApplication app;
            var siteCollection = properties.Feature.Parent as SPSite;
            if (siteCollection != null)
            {
                app = siteCollection.WebApplication;
            }
            else
            {
                var site = properties.Feature.Parent as SPWeb;
                if (site == null)
                {
                    throw new SPException("Cannot setup connectionstring");
                }
                app = site.Site.WebApplication;
            }
            var modification1 = new SPWebConfigModification();
            modification1.Path = "configuration";
            modification1.Name = "connectionStrings";
            modification1.Value = "<connectionStrings> </connectionStrings>";
            modification1.Owner = Assembly.GetExecutingAssembly().FullName;
            modification1.Sequence = 100;
            modification1.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection;
            app.WebConfigModifications.Add(modification1);

            var modification2 = new SPWebConfigModification();
            modification2.Path = "configuration/connectionStrings";
            modification2.Name = "add[@name='ActivityFeed']";
            modification2.Value = string.Format(CultureInfo.InvariantCulture, "<add name='ActivityFeed' connectionString='{0}' /> ", this.GetActivityFeedConectionString());
                //Properties.Resources.ActivityFeedConectionString);
            modification2.Owner = Assembly.GetExecutingAssembly().FullName;
            modification2.Sequence = 100;
            modification2.Type =SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            app.WebConfigModifications.Add(modification2);

            var service = SPFarm.Local.Services.GetValue<SPWebService>();
            app.Update();            
            service.ApplyWebConfigModifications();
        }

        protected abstract string GetActivityFeedConectionString();

        // Uncomment the method below to handle the event raised before a feature is uninstalled.

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
        }

        // Uncomment the method below to handle the event raised when a feature is upgrading.

        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}
    }
}
